package com.xuecheng.base.exception;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 星河一叶Ck
 * @date 2025/4/21
 */

@Slf4j
@RestControllerAdvice // 就是controllerAdvice和ResponseBody的合体 ResponseBody是返回json数据
public class GlobalExceptionHandler {

    /**
     * 添加ExceptionHandler 就是拦截的作用 然后里面给的是XueChengPlusException
     * 表示如果controller层抛出了这个异常 那么就自动捕获 而如果是service抛出 service抛出会向上
     * 那么还是到controller层 然后controller层还是抛出到框架
     * @param e
     * @return
     */
    @ExceptionHandler(XueChengPlusException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public RestErrorResponse  customException (XueChengPlusException e) {
        log.error("系统异常:{}",e.getErrMessage(), e);
        return new RestErrorResponse(e.getErrMessage());
    }

    // 其他的异常全部走这个
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public RestErrorResponse exception (Exception e) {
        log.error("【系统异常】{}",e.getMessage(),e);
        // 未知的执行错误
        return new RestErrorResponse(CommonError.UNKNOWN_ERROR.getErrMessage());
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public RestErrorResponse methodArgumentNotValidException (MethodArgumentNotValidException e) {
        // 获取到异常信息
        BindingResult bindingResult = e.getBindingResult();
        // 创建一个集合 因为异常信息可能有多条异常 所以我们可以遍历插入到创建的集合中
        // 最后将其全部以逗号隔开 拼接在一起
        List<String> msgList = new ArrayList<>();
        // FieldError: 字段异常 也就是返回多个错误信息字段
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        fieldErrors.stream().forEach(item -> {
            // 遍历错误信息 然后获取信息的内容 然后插入到集合中
            msgList.add(item.getDefaultMessage());
        });
        String errMessage = StringUtils.join(msgList, ",");// 拼接起来以逗号隔开
        log.error("【系统异常】{}",errMessage);
        return new RestErrorResponse(errMessage);
    }

}
